﻿#ifndef ALARM_H
#define ALARM_H

//#include <pthread.h>
#include <windows.h>
#include <stdio.h>
#include <list>
#include <iostream>
#include <concrt.h>


using namespace std;
using namespace Concurrency;

#include "cv.h"
#include "../Packets/jsbytearray.h"
#include "../Packets/package.h"
#include "../DIB/dib.h"
#include "../Socket/socket.h"
#include "../Public/public.h"

extern IplImage * cvCvtDIB2IMG(CDIB * pDib);
extern CDIB * cvCvtIMG2DIB(IplImage * pImg);

#define CHANNELNUM 2

typedef struct
{
    DWORD nPackageID; //信号包ID
    BYTE nChannelNO; //通道号
} ChannelStatus;

typedef struct
{
    ATM_AlarmInfo alarmInfo;
    Rects rects;
    IplImage *pIplImage;
    bool ackknowleged;
} AlarmNet;

typedef list<AlarmNet> BackupAlarms;

class CSocket;

//CAlarm类主要负责报警信息的管理
//1.报警数据由SendAlarm放入，SetSocket设置的socket发出
//2.CAlarm类会维护一个备份数据，并起一路线程进行放送
//3.相同的报警信息不会重复发送，因此得记录每次的报警情况，以便新的报警信息能与之对比
//  有报警则用SendAlarm记录，没有则NoAlarm
class CAlarm
{
public:
    CAlarm();
    ~CAlarm();

    void SetSocket(CSocket *pSock);

    int SendAlarm(ATM_AlarmInfo &alarmInfo, Rects &rects, IplImage *alarmImage);
    void NoAlarm();  //图像检测到没有报警信息（非稳定状态）时调用，用于清除上次报警记录

    void AlarmAckHandle(char *buffer);

    BYTE GetAlarmAckInfo();    //由CVProcess类取得报警的回应信息，作出是否更新背景等操作
    void ResetAlarmAckInfo();  //每次取得报警回应信息后，要重置一下

private:
    static DWORD WINAPI WorkThread(void *arg); //发送备份报警线程
    void Run(); //运行线程函数

    void ClearAllBackupAlarm();
    void ClearAllChannelStatus();

    bool CampareAlarm(Rects &rects);

    //for debug
    void Print(Rects &rects);

private:
    DWORD m_backupAlarmSendTh;

    int m_nWarnID;
    int m_nChannelStatus[CHANNELNUM];

    //0x00------不改新背景,说是障碍物
    //0x01------改新背景，说明不是障碍物
    volatile BYTE m_AckInfo;

    BackupAlarms m_backupAlarms;
    Rects m_LastAlarmRects;

private:
    CSocket *m_pSocket;
    critical_section m_locker;

};

#endif

